/********************************************************************************/
/*   The  Software  is  proprietary,  confidential,  and  valuable to Realtek   */
/*   Semiconductor  Corporation  ("Realtek").  All  rights, including but not   */
/*   limited  to  copyrights,  patents,  trademarks, trade secrets, mask work   */
/*   rights, and other similar rights and interests, are reserved to Realtek.   */
/*   Without  prior  written  consent  from  Realtek,  copying, reproduction,   */
/*   modification,  distribution,  or  otherwise  is strictly prohibited. The   */
/*   Software  shall  be  kept  strictly  in  confidence,  and  shall  not be   */
/*   disclosed to or otherwise accessed by any third party.                     */
/*   c<2003> - <2012>                                                           */
/*   The Software is provided "AS IS" without any warranty of any kind,         */
/*   express, implied, statutory or otherwise.                                  */
/********************************************************************************/

//----------------------------------------------------------------------------------------------------
// ID Code      : SysTypeC.c No.0000
// Update Note  :
//----------------------------------------------------------------------------------------------------

#define __SYSTEM_TYPC_C__

#include "SysInclude.h"

#if(_DP_TYPE_C_SUPPORT == _ON)
//****************************************************************************
// DEFINITIONS / MACROS
//****************************************************************************
//--------------------------------------------------
// Time of Type-C Cable Recheck After Reconnected When DP_TYPE_C_CONNECTION_CHECK_WAY != _DISCRETE_PORT_CTRL_USE_GPIO
//--------------------------------------------------
#define _TYPE_C_RESTART_CHECK_CABLE_STATUS_TIME         500 // Restart time 0.5s for after type-c reconnected

#define GET_TYPE_C_STATE(x)                             (g_pstTypeCStatus[SysTypeCGetTypeCIndex(x)].enumTypeCState)
#define SET_TYPE_C_STATE(x, y)                          (g_pstTypeCStatus[SysTypeCGetTypeCIndex(x)].enumTypeCState = (y))

#define GET_TYPE_C_PIN_ASSIGNMENT(x)                    (g_pstTypeCStatus[SysTypeCGetTypeCIndex(x)].enumSPinAssignment)
#define SET_TYPE_C_PIN_ASSIGNMENT(x, y)                 (g_pstTypeCStatus[SysTypeCGetTypeCIndex(x)].enumSPinAssignment = (y))

#define GET_TYPE_C_CAPABILITY_CHG(x)                    (g_pstTypeCStatus[SysTypeCGetTypeCIndex(x)].b1CapChangeFlag)
#define SET_TYPE_C_CAPABILITY_CHG(x)                    (g_pstTypeCStatus[SysTypeCGetTypeCIndex(x)].b1CapChangeFlag = _TRUE)
#define CLR_TYPE_C_CAPABILITY_CHG(x)                    (g_pstTypeCStatus[SysTypeCGetTypeCIndex(x)].b1CapChangeFlag = _FALSE)

//****************************************************************************
// STRUCT / TYPE / ENUM DEFINITTIONS
//****************************************************************************
typedef enum
{
    _TYPE_C_UNATTACH_STATE        = 0x00,
    _TYPE_C_ATTACHED_STATE        = 0x01,
    _TYPE_C_ALT_MODE_READY_STATE  = 0x02,
    _TYPE_C_RECONNECT_STATE       = 0x03,
}EnumTypeCState;

// USB Type-C Related Status
typedef struct
{
    EnumTypeCState enumTypeCState;
    // -----------------------------
    EnumTypeCPinCfgType enumSPinAssignment;
    // -----------------------------
    BYTE b1CapChangeFlag : 1;
}StructTypeCStatus;

//****************************************************************************
// CODE TABLES
//****************************************************************************


//****************************************************************************
// VARIABLE DECLARATIONS
//****************************************************************************
StructTypeCStatus g_pstTypeCStatus[_TYPE_C_PORT_VALID];

#if(_D0_DP_USB_HUB_SUPPORT == _ON)
StructUsbHubInfo g_stD0UsbHubInfo;
#endif

#if(_D1_DP_USB_HUB_SUPPORT == _ON)
StructUsbHubInfo g_stD1UsbHubInfo;
#endif

#if(_D6_DP_USB_HUB_SUPPORT == _ON)
StructUsbHubInfo g_stD6UsbHubInfo;
#endif

//****************************************************************************
// FUNCTION DECLARATIONS
//****************************************************************************
void SysTypeCInitial(void);
void SysTypeCHandler(void);
void SysTypeCUFPHandler(BYTE ucInputPort);
void SysTypeCPowerSwitch(EnumPowerAction enumSwitch);
EnumTypeCAttachStatus SysTypeCGetPortControllerCcAttach(BYTE ucInputPort);
EnumTypeCAltModeStatus SysTypeCGetPortControllerAltModeReady(BYTE ucInputPort);
bit SysTypeCGetPortControllerPinAssignment(BYTE ucInputPort);
void SysTypeCCapabilityChangeProc(BYTE ucInputPort);
bit SysTypeCReconnect(BYTE ucInputPort);
void SysTypeCReconnectTransition(BYTE ucInputPort);
bit SysTypeCUpdatePortControllerConfig(BYTE ucInputPort);
bit SysTypeCGetCcAttach(BYTE ucInputPort);
bit SysTypeCGetAltModeReady(BYTE ucInputPort);
BYTE SysTypeCGetTypeCIndex(BYTE ucInputPort);
EnumDpLaneCount SysTypeCGetAltModeLaneCnt(EnumTypeCPinCfgType enumPinAssignment);
void SysTypeCSwitchOSDLaneCount(BYTE ucInputPort, EnumDpLaneCount enumDpLaneCount);
void SysTypeCSetCapabilityChangeFlag(BYTE ucInputPort);

#if(((_D0_DP_TYPE_C_SUPPORT == _ON) && (_D0_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS)) || ((_D1_DP_TYPE_C_SUPPORT == _ON) && (_D1_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS)) || ((_D6_DP_TYPE_C_SUPPORT == _ON) && (_D6_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS)))
void SysTypeCSwitchToUnattachState(BYTE ucInputPort);
#endif
void SysTypeCCancelUnattachTimerEvent(BYTE ucInputPort);

#if(_DP_USB_HUB_SUPPORT == _ON)
BYTE SysTypeCGetDpLaneCount(BYTE ucInputPort);
void SysTypeCUsbHubProc(BYTE ucInputPort);
void SysTypeCUsbHubDetectProc(BYTE ucInputPort);
void SysTypeCUsbHubConfigProc(BYTE ucInputPort, BYTE ucDpLanes);
WORD SysTypeCGetUsbHubSetU3ReadyDelayTime(BYTE ucInputPort);

#if(_D0_DP_USB_HUB_SUPPORT == _ON)
void SysTypeCD0UsbHubDetectProc(void);
#endif
#if(_D1_DP_USB_HUB_SUPPORT == _ON)
void SysTypeCD1UsbHubDetectProc(void);
#endif
#if(_D6_DP_USB_HUB_SUPPORT == _ON)
void SysTypeCD6UsbHubDetectProc(void);
#endif

void SysTypeCOsdHubProc(void);
bit SysTypeCGetUsbHubChangeFlg(BYTE ucInputPort);
BYTE SysTypeCGetUsbHubDeviceInfo(BYTE ucInputPort);
#endif

#endif // End of #if(_DP_TYPE_C_SUPPORT == _ON)

//****************************************************************************
// FUNCTION DEFINITIONS
//****************************************************************************
#if(_DP_TYPE_C_SUPPORT == _ON)
//--------------------------------------------------
// Description  : TypeC AC On Initial Setting
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void SysTypeCInitial(void)
{
#if(_D0_DP_TYPE_C_SUPPORT == _ON)

    SET_TYPE_C_STATE(_D0_INPUT_PORT, _TYPE_C_UNATTACH_STATE);
    SET_TYPE_C_PIN_ASSIGNMENT(_D0_INPUT_PORT, _TYPE_C_PIN_ASSIGNMENT_NONE);
    CLR_TYPE_C_CAPABILITY_CHG(_D0_INPUT_PORT);

#if(_D0_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK == _DISCRETE_PORT_CTRL_USE_SMBUS)
    UserCommonPortControllerSetD0I2CDetection();
#endif
#endif  // End Of #if(_D0_DP_TYPE_C_SUPPORT == _ON)


#if(_D1_DP_TYPE_C_SUPPORT == _ON)

    SET_TYPE_C_STATE(_D1_INPUT_PORT, _TYPE_C_UNATTACH_STATE);
    SET_TYPE_C_PIN_ASSIGNMENT(_D1_INPUT_PORT, _TYPE_C_PIN_ASSIGNMENT_NONE);
    CLR_TYPE_C_CAPABILITY_CHG(_D1_INPUT_PORT);

#if(_D1_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK == _DISCRETE_PORT_CTRL_USE_SMBUS)
    UserCommonPortControllerSetD1I2CDetection();
#endif
#endif // End Of #if(_D1_DP_TYPE_C_SUPPORT == _ON)


#if(_D6_DP_TYPE_C_SUPPORT == _ON)

    SET_TYPE_C_STATE(_D6_INPUT_PORT, _TYPE_C_UNATTACH_STATE);
    SET_TYPE_C_PIN_ASSIGNMENT(_D6_INPUT_PORT, _TYPE_C_PIN_ASSIGNMENT_NONE);
    CLR_TYPE_C_CAPABILITY_CHG(_D6_INPUT_PORT);

#if(_D6_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK == _DISCRETE_PORT_CTRL_USE_SMBUS)
    UserCommonPortControllerSetD6I2CDetection();
#endif
#endif // End Of #if(_D6_DP_TYPE_C_SUPPORT == _ON)
}

//--------------------------------------------------
// Description  : PD/CC Process
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void SysTypeCHandler(void)
{
#if(_D0_DP_TYPE_C_SUPPORT == _ON)
#if(_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
    // 1. Run PD/CC Proc (For Embedded Port Controller Only)
    ScalerTypeCHandler(_D0_INPUT_PORT);

#if(_USB3_RETIMER_SUPPORT == _ON)
    ScalerUSB3RetimerHandler(GET_POWER_STATUS());
#endif
#endif

    // 2. Run DFP Proc According to Port Controller Status (For All Type-C Ports)
    SysTypeCUFPHandler(_D0_INPUT_PORT);

#if(_D0_DP_USB_HUB_SUPPORT == _ON)
    // 3. Rub Hub Proc if Hub Support
    SysTypeCUsbHubProc(_D0_INPUT_PORT);
#endif
#endif  // End Of #if(_D0_DP_TYPE_C_SUPPORT == _ON)


#if(_D1_DP_TYPE_C_SUPPORT == _ON)
#if(_D1_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
    ScalerTypeCHandler(_D1_INPUT_PORT);
#endif

    SysTypeCUFPHandler(_D1_INPUT_PORT);

#if(_D1_DP_USB_HUB_SUPPORT == _ON)
    SysTypeCUsbHubProc(_D1_INPUT_PORT);
#endif
#endif  // End Of #if(_D1_DP_TYPE_C_SUPPORT == _ON)


#if(_D6_DP_TYPE_C_SUPPORT == _ON)
#if(_D6_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
    ScalerTypeCHandler(_D6_INPUT_PORT);
#endif

    SysTypeCUFPHandler(_D6_INPUT_PORT);

#if(_D6_DP_USB_HUB_SUPPORT == _ON)
    SysTypeCUsbHubProc(_D6_INPUT_PORT);
#endif
#endif  // End Of #if(_D6_DP_TYPE_C_SUPPORT == _ON)
}

//--------------------------------------------------
// Description  : Type-C Handler Used to Sync Port Controller and Scaler
// Input Value  : ucInputPort --> Inputput
// Output Value : None
//--------------------------------------------------
void SysTypeCUFPHandler(BYTE ucInputPort)
{
    switch(GET_TYPE_C_STATE(ucInputPort))
    {
        case _TYPE_C_UNATTACH_STATE:

            // Check if CC Attached
            if(SysTypeCGetPortControllerCcAttach(ucInputPort) == _TYPE_C_ATTACH)
            {
                DebugMessageSystem("8. [TYPE C] CC Unattach at SysTypeC State:", _TYPE_C_UNATTACH_STATE);

                SET_TYPE_C_STATE(ucInputPort, _TYPE_C_ATTACHED_STATE);
            }

            break;

        case _TYPE_C_ATTACHED_STATE:

            // Check if CC Attached
            if(SysTypeCGetPortControllerCcAttach(ucInputPort) == _TYPE_C_ATTACH)
            {
                // Check if PD Has Entered Alt. Mode (Wait For PD Power Contract / Swap / Alt Mode Flow)
                if(SysTypeCGetPortControllerAltModeReady(ucInputPort) == _TYPE_C_ALT_MODE_READY)
                {
                    // 1. Get Alt. Mode Pin Assignment and Proc Related Setting (Lane Mapping or Swap)
                    if(SysTypeCGetPortControllerPinAssignment(ucInputPort) == _SUCCESS)
                    {
                        // 2. Update OSD Lane Count According to Alt. Mode Pin Assignment
                        SysTypeCSwitchOSDLaneCount(ucInputPort, SysTypeCGetAltModeLaneCnt(GET_TYPE_C_PIN_ASSIGNMENT(ucInputPort)));
                        // SysTypeCSwitchSysDataLaneCount();

                        // 3. Switch DP Lane Count According to Alt. Mode Pin Assignment
                        ScalerDpLaneCountSwitch(ucInputPort, SysTypeCGetAltModeLaneCnt(GET_TYPE_C_PIN_ASSIGNMENT(ucInputPort)));

                        DebugMessageSystem("8. [TYPE C] Alt Mode Ready at SysTypeC State:", _TYPE_C_ATTACHED_STATE);

                        SET_TYPE_C_STATE(ucInputPort, _TYPE_C_ALT_MODE_READY_STATE);
                    }
                }
            }
            else
            {
                DebugMessageSystem("8. [TYPE C] CC Unattach at SysTypeC State:", _TYPE_C_ATTACHED_STATE);

                SET_TYPE_C_STATE(ucInputPort, _TYPE_C_UNATTACH_STATE);
            }

            break;

        case _TYPE_C_ALT_MODE_READY_STATE:

            // Check if CC Attached
            if(SysTypeCGetPortControllerCcAttach(ucInputPort) == _TYPE_C_ATTACH)
            {
                // Check if Current Config Matches the Latest Requirement, Otherwise Switch to Reconnect
                if((GET_TYPE_C_CAPABILITY_CHG(ucInputPort) == _TRUE) && (SysTypeCUpdatePortControllerConfig(ucInputPort) == _SUCCESS))
                {
                    SysTypeCCapabilityChangeProc(ucInputPort);
                }
                else if(SysTypeCGetPortControllerAltModeReady(ucInputPort) != _TYPE_C_ALT_MODE_READY)
                {
                    DebugMessageSystem("8. [TYPE C] Alt Mode Not Ready at SysTypeC State:", _TYPE_C_ALT_MODE_READY_STATE);

                    // Config Lane Mapping to USB + DP Mode, and Back to Attached State to Wait for Alt. Mode Ready
                    SET_TYPE_C_STATE(ucInputPort, _TYPE_C_ATTACHED_STATE);
                }
            }
            else
            {
                DebugMessageSystem("8. [TYPE C] CC Unattach at SysTypeC State:", _TYPE_C_ALT_MODE_READY_STATE);

                SET_TYPE_C_STATE(ucInputPort, _TYPE_C_UNATTACH_STATE);
            }

            break;

        case _TYPE_C_RECONNECT_STATE:

            if(SysTypeCGetPortControllerCcAttach(ucInputPort) == _TYPE_C_ATTACH)
            {
                if(SysTypeCGetPortControllerAltModeReady(ucInputPort) == _TYPE_C_ALT_MODE_READY)
                {
                    if(GET_TYPE_C_CAPABILITY_CHG(ucInputPort) == _TRUE)
                    {
                        if(SysTypeCReconnect(ucInputPort) == _SUCCESS)
                        {
                            CLR_TYPE_C_CAPABILITY_CHG(ucInputPort);

                            // State Transition After Reconnect
                            SysTypeCReconnectTransition(ucInputPort);
                        }
                    }
                }
                else
                {
                    SET_TYPE_C_STATE(ucInputPort, _TYPE_C_ATTACHED_STATE);
                }
            }
            else
            {
                // If Port Controller Switch to Unattach in 500ms, Cancel Unatach Timer Event
                SysTypeCCancelUnattachTimerEvent(ucInputPort);

                SET_TYPE_C_STATE(ucInputPort, _TYPE_C_UNATTACH_STATE);
            }

            break;

        default:

            // Error Handling ?????

            break;
    }
}

//--------------------------------------------------
// Description  : Set Capability Change Power Switch Proc
// Input Value  : enumSwitch
// Output Value : None
//--------------------------------------------------
void SysTypeCPowerSwitch(EnumPowerAction enumSwitch)
{
    switch(enumSwitch)
    {
        case _POWER_ACTION_AC_ON_TO_NORMAL:
        case _POWER_ACTION_OFF_TO_NORMAL:
        case _POWER_ACTION_PS_TO_NORMAL:
        case _POWER_ACTION_OFF_TO_FAKE_OFF:

            // Reset Change Port Controller Capability Flag
#if(_D0_DP_TYPE_C_SUPPORT == _ON)
            SET_TYPE_C_CAPABILITY_CHG(_D0_INPUT_PORT);
#endif

#if(_D1_DP_TYPE_C_SUPPORT == _ON)
            SET_TYPE_C_CAPABILITY_CHG(_D1_INPUT_PORT);
#endif

#if(_D6_DP_TYPE_C_SUPPORT == _ON)
            SET_TYPE_C_CAPABILITY_CHG(_D6_INPUT_PORT);
#endif

            DebugMessageSystem("8. Type-C Reset Power Proc", enumSwitch);

            break;

        case _POWER_ACTION_NORMAL_TO_PS:
        case _POWER_ACTION_NORMAL_TO_OFF:

            break;

        default:

            break;
    }
}

//--------------------------------------------------
// Description  : Get Port Controller CC Attached Info (5400 & User : From GPIO / Embedded From : CC Attach Flag)
// Input Value  : ucInputPort --> Inputput
// Output Value : CC Attach Status (_TRUE / _FALSE)
//--------------------------------------------------
EnumTypeCAttachStatus SysTypeCGetPortControllerCcAttach(BYTE ucInputPort)
{
    switch(ucInputPort)
    {
#if(_D0_DP_TYPE_C_SUPPORT == _ON)
        case _D0_INPUT_PORT:
#if(_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
            return ScalerTypeCGetCcAttach(ucInputPort);

#elif((_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_RTS5400_SERIES) || (_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_USER))
            return UserCommonPortControllerGetCcAttach(ucInputPort);
#endif
            break;
#endif  // End of #if(_D0_DP_TYPE_C_SUPPORT == _ON)

#if(_D1_DP_TYPE_C_SUPPORT == _ON)
        case _D1_INPUT_PORT:

#if(_D1_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
            return ScalerTypeCGetCcAttach(ucInputPort);

#elif((_D1_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_RTS5400_SERIES) || (_D1_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_USER))
            return UserCommonPortControllerGetCcAttach(ucInputPort);
#endif
            break;
#endif  // End of #if(_D1_DP_TYPE_C_SUPPORT == _ON)

#if(_D6_DP_TYPE_C_SUPPORT == _ON)
        case _D6_INPUT_PORT:

#if(_D6_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
            return ScalerTypeCGetCcAttach(ucInputPort);
#elif((_D6_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_RTS5400_SERIES) || (_D6_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_USER))
            return UserCommonPortControllerGetCcAttach(ucInputPort);
#endif
            break;
#endif  // End of #if(_D6_DP_TYPE_C_SUPPORT == _ON)

        default:

            return _TYPE_C_UNATTACH;

            break;
    }
    return _TYPE_C_UNATTACH;
}

//--------------------------------------------------
// Description  : Get Port Controller Alt. Mode Ready Info (5400 & User : From GPIO / Embedded From : Alt Mode Ready Flag)
// Input Value  : ucInputPort --> Inputput
// Output Value : Alt. Mode Ready Status (_TRUE / _FALSE)
//--------------------------------------------------
EnumTypeCAltModeStatus SysTypeCGetPortControllerAltModeReady(BYTE ucInputPort)
{
    switch(ucInputPort)
    {
#if(_D0_DP_TYPE_C_SUPPORT == _ON)
        case _D0_INPUT_PORT:

#if(_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
            return ScalerTypeCGetAltModeReady(ucInputPort);
#elif((_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_RTS5400_SERIES) || (_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_USER))
            return UserCommonPortControllerGetAltModeReady(ucInputPort);
#endif
            break;
#endif

#if(_D1_DP_TYPE_C_SUPPORT == _ON)
        case _D1_INPUT_PORT:

#if(_D1_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
            return ScalerTypeCGetAltModeReady(ucInputPort);
#elif((_D1_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_RTS5400_SERIES) || (_D1_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_USER))
            return UserCommonPortControllerGetAltModeReady(ucInputPort);
#endif
            break;
#endif

#if(_D6_DP_TYPE_C_SUPPORT == _ON)
        case _D6_INPUT_PORT:

#if(_D6_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
            return ScalerTypeCGetAltModeReady(ucInputPort);
#elif((_D6_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_RTS5400_SERIES) || (_D6_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_USER))
            return UserCommonPortControllerGetAltModeReady(ucInputPort);
#endif
            break;
#endif

        default:

            return _TYPE_C_ALT_MODE_NOT_READY;

            break;
    }
    return _TYPE_C_ALT_MODE_NOT_READY;
}

//--------------------------------------------------
// Description  : Get Port Controller Pin Assignment (5400 & User : From I2C / Embedded From : Pin Assignment Flag)
// Input Value  : ucInputPort --> Inputput
// Output Value : Reconnect Status (_SUCCESS / _FAIL)
//--------------------------------------------------
bit SysTypeCGetPortControllerPinAssignment(BYTE ucInputPort)
{
    EnumTypeCPinCfgType enumPinAssignment = _TYPE_C_PIN_ASSIGNMENT_NONE;

    switch(ucInputPort)
    {
#if(_D0_DP_TYPE_C_SUPPORT == _ON)
        case _D0_INPUT_PORT:

#if(_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
            if(ScalerTypeCGetPinAssignment(_D0_INPUT_PORT, &enumPinAssignment) == _SUCCESS)
#elif(_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_RTS5400_SERIES)
            if(UserCommonPortControllerGet5400PinAssignment(_D0_INPUT_PORT, &enumPinAssignment) == _SUCCESS)
#elif(_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_USER)
            if(UserCommonPortControllerGetUserPinAssignment(_D0_INPUT_PORT, &enumPinAssignment) == _SUCCESS)
#endif
            {
                DebugMessageSystem("8. SysTypeC Get Port Controller Pin Assignment Type :", enumPinAssignment);

                SET_TYPE_C_PIN_ASSIGNMENT(_D0_INPUT_PORT, enumPinAssignment);

                return _SUCCESS;
            }
            else
            {
                SET_TYPE_C_PIN_ASSIGNMENT(_D0_INPUT_PORT, _TYPE_C_PIN_ASSIGNMENT_NONE);

                return _FAIL;
            }

            break;
#endif  // End of #if(_D0_DP_TYPE_C_SUPPORT == _ON)

#if(_D1_DP_TYPE_C_SUPPORT == _ON)
        case _D1_INPUT_PORT:

            break;
#endif  // End of #if(_D1_DP_TYPE_C_SUPPORT == _ON)

#if(_D6_DP_TYPE_C_SUPPORT == _ON)
        case _D6_INPUT_PORT:

            break;
#endif  // End of #if(_D6_DP_TYPE_C_SUPPORT == _ON)

        default:

            DebugMessageSystem("8. SysTypeC Get Port Controller with Invalid Port :", ucInputPort);

            SET_TYPE_C_PIN_ASSIGNMENT(ucInputPort, _TYPE_C_PIN_ASSIGNMENT_NONE);

            return _FAIL;

            break;
    }
    return _FAIL;
}

//--------------------------------------------------
// Description  : Check if Current Config Matches the Latest Requirement, and Set to Reconnect State
// Input Value  : ucInputPort --> Inputput
// Output Value : None
//--------------------------------------------------
void SysTypeCCapabilityChangeProc(BYTE ucInputPort)
{
    if(GET_TYPE_C_PIN_ASSIGNMENT(ucInputPort) != _TYPE_C_PIN_ASSIGNMENT_E)
    {
        if(((UserInterfaceTypeCGetOsdU3ModeSelection(ucInputPort) == _TYPE_C_U3_ON) && (GET_TYPE_C_PIN_ASSIGNMENT(ucInputPort) != _TYPE_C_PIN_ASSIGNMENT_D)) ||
           ((UserInterfaceTypeCGetOsdU3ModeSelection(ucInputPort) == _TYPE_C_U3_OFF) && (GET_TYPE_C_PIN_ASSIGNMENT(ucInputPort) == _TYPE_C_PIN_ASSIGNMENT_D)))
        {
            DebugMessageSystem("8. CapabilityChangeProc -> U3 Mode and Pin Assignment Mismatch, Set State to :", _TYPE_C_RECONNECT_STATE);

            SET_TYPE_C_STATE(ucInputPort, _TYPE_C_RECONNECT_STATE);
        }
        else
        {
            // Current Config Matched the Latest Capability
            CLR_TYPE_C_CAPABILITY_CHG(ucInputPort);
        }
    }
    else
    {
        // Pin Assignment E Cable, Ignore Capability Change, Since Port Controller Should Alway Choose E (No USB3)
        CLR_TYPE_C_CAPABILITY_CHG(ucInputPort);
    }
}

//--------------------------------------------------
// Description  : Request Port Controller to Reconnect
// Input Value  : ucInputPort --> Inputput
// Output Value : Reconnect Status (_SUCCESS / _FAIL)
//--------------------------------------------------
bit SysTypeCReconnect(BYTE ucInputPort)
{
    switch(ucInputPort)
    {
#if(_D0_DP_TYPE_C_SUPPORT == _ON)
        case _D0_INPUT_PORT:

#if(_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
            return ScalerTypeCReconnect(_D0_INPUT_PORT);
#elif(_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_RTS5400_SERIES)
            return UserCommonPortController5400Reconnect(_D0_INPUT_PORT);
#elif(_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_USER)
            return UserCommonPortControllerUserReconnect(_D0_INPUT_PORT);
#endif
            break;
#endif

#if(_D1_DP_TYPE_C_SUPPORT == _ON)
        case _D1_INPUT_PORT:

#if(_D1_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
            return ScalerTypeCReconnect(_D1_INPUT_PORT);
#elif(_D1_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_RTS5400_SERIES)
            return UserCommonPortController5400Reconnect(_D1_INPUT_PORT);
#elif(_D1_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_USER)
            return UserCommonPortControllerUserReconnect(_D1_INPUT_PORT);
#endif
            break;
#endif

#if(_D6_DP_TYPE_C_SUPPORT == _ON)
        case _D6_INPUT_PORT:

#if(_D6_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
            return ScalerTypeCReconnect(_D6_INPUT_PORT);
#elif(_D6_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_RTS5400_SERIES)
            return UserCommonPortController5400Reconnect(_D6_INPUT_PORT);
#elif(_D6_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_USER)
            return UserCommonPortControllerUserReconnect(_D6_INPUT_PORT);
#endif
            break;
#endif

        default:

            return _FAIL;

            break;
    }
    return _FAIL;
}

//--------------------------------------------------
// Description  : Transit Type C State After Reconnect Success
// Input Value  : ucInputPort --> Inputput
// Output Value : Reconnect Status (_SUCCESS / _FAIL)
//--------------------------------------------------
void SysTypeCReconnectTransition(BYTE ucInputPort)
{
    switch(ucInputPort)
    {
#if(_D0_DP_TYPE_C_SUPPORT == _ON)
        case _D0_INPUT_PORT:
#if(_D0_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK == _DISCRETE_PORT_CTRL_USE_SMBUS)
            // Set CC Attach & Alt Mode Ready to False
            SET_D0_CABLE_STATUS(_FALSE);
            SET_D0_DP_TYPE_C_ALTMODE_STATUS(_FALSE);

            // Set TypeC State to Unattach
            SET_TYPE_C_STATE(_D0_INPUT_PORT, _TYPE_C_UNATTACH_STATE);

            // Restart CC Attach & Alt. Mode Ready Detection By I2C Later
            UserCommonPortControllerRestartD0I2CDetection(_TYPE_C_RESTART_CHECK_CABLE_STATUS_TIME);
#else
            // If Port Controller Not Switch to Unattach in 500ms, Force Switch to Unattach State
            ScalerTimerActiveTimerEvent(SEC(0.5), _SYSTEM_TIMER_EVENT_D0_TYPE_C_UNATTACH);
#endif
            break;
#endif  // End of #if(_D0_DP_TYPE_C_SUPPORT == _ON)

#if(_D1_DP_TYPE_C_SUPPORT == _ON)
        case _D1_INPUT_PORT:
#if(_D1_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK == _DISCRETE_PORT_CTRL_USE_SMBUS)
            // Set CC Attach & Alt Mode Ready to False
            SET_D1_CABLE_STATUS(_FALSE);
            SET_D1_DP_TYPE_C_ALTMODE_STATUS(_FALSE);

            // Set TypeC State to Unattach
            SET_TYPE_C_STATE(_D1_INPUT_PORT, _TYPE_C_UNATTACH_STATE);

            // Restart CC Attach & Alt. Mode Ready Detection By I2C Later
            UserCommonPortControllerRestartD1I2CDetection(_TYPE_C_RESTART_CHECK_CABLE_STATUS_TIME);
#else
            // If Port Controller Not Switch to Unattach in 500ms, Force Switch to Unattach State
            ScalerTimerActiveTimerEvent(SEC(0.5), _SYSTEM_TIMER_EVENT_D1_TYPE_C_UNATTACH);
#endif
            break;
#endif  // End of #if(_D1_DP_TYPE_C_SUPPORT == _ON)

#if(_D6_DP_TYPE_C_SUPPORT == _ON)
        case _D6_INPUT_PORT:
#if(_D6_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK == _DISCRETE_PORT_CTRL_USE_SMBUS)
            // Set CC Attach & Alt Mode Ready to False
            SET_D6_CABLE_STATUS(_FALSE);
            SET_D6_DP_TYPE_C_ALTMODE_STATUS(_FALSE);

            // Set TypeC State to Unattach
            SET_TYPE_C_STATE(_D6_INPUT_PORT, _TYPE_C_UNATTACH_STATE);

            // Restart CC Attach & Alt. Mode Ready Detection By I2C Later
            UserCommonPortControllerRestartD6I2CDetection(_TYPE_C_RESTART_CHECK_CABLE_STATUS_TIME);
#else
            // If Port Controller Not Switch to Unattach in 500ms, Force Switch to Unattach State
            ScalerTimerActiveTimerEvent(SEC(0.5), _SYSTEM_TIMER_EVENT_D6_TYPE_C_UNATTACH);
#endif
            break;
#endif  // End of #if(_D6_DP_TYPE_C_SUPPORT == _ON)

        default:

            break;
    }
}

//--------------------------------------------------
// Description  : Update Port Controller Configuration
// Input Value  : ucInputPort --> Inputput
// Output Value : Reconnect Status (_SUCCESS / _FAIL)
//--------------------------------------------------
bit SysTypeCUpdatePortControllerConfig(BYTE ucInputPort)
{
    // Default Set U3 Mode to OFF
    EnumTypeCU3ModeType enumU3Mode = _TYPE_C_U3_OFF;
    EnumTypeCMultiFuncStatus enumMultiFunc = _TYPE_C_MULTI_FUNC_NOT_PREFER;
    EnumTypeCPinCfgCapType enumPinAssignmentCap = _TYPE_C_PIN_ASSIGNMENT_CAP_NONE;

    // Update U3 Mode / Multi-Function Bit / Pin Assignment Capability (From User)
    if(UserInterfaceTypeCGetOsdU3ModeSelection(ucInputPort) == _TYPE_C_U3_ON)
    {
        enumU3Mode = _TYPE_C_U3_ON;
        enumMultiFunc = _TYPE_C_MULTI_FUNC_PREFER;
    }

    enumPinAssignmentCap = UserInterfaceTypeCGetPinConfigType(ucInputPort, enumU3Mode);

    switch(ucInputPort)
    {
#if(_D0_DP_TYPE_C_SUPPORT == _ON)
        case _D0_INPUT_PORT:

#if(_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
            return ScalerTypeCUpdateConfig(_D0_INPUT_PORT, enumMultiFunc, enumPinAssignmentCap);
#elif((_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_RTS5400_SERIES) || (_D0_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_USER))
            return UserCommonPortControllerUpdateConfig(_D0_INPUT_PORT, enumMultiFunc, enumPinAssignmentCap);
#endif
            break;
#endif

#if(_D1_DP_TYPE_C_SUPPORT == _ON)
        case _D1_INPUT_PORT:

#if(_D1_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
            return ScalerTypeCUpdateConfig(_D1_INPUT_PORT, enumMultiFunc, enumPinAssignmentCap);
#elif((_D1_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_RTS5400_SERIES) || (_D1_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_USER))
            return UserCommonPortControllerUpdateConfig(_D1_INPUT_PORT, enumMultiFunc, enumPinAssignmentCap);
#endif
            break;
#endif

#if(_D6_DP_TYPE_C_SUPPORT == _ON)
        case _D6_INPUT_PORT:

#if(_D6_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_EMBEDDED)
            return ScalerTypeCUpdateConfig(_D6_INPUT_PORT, enumMultiFunc, enumPinAssignmentCap);
#elif((_D6_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_RTS5400_SERIES) || (_D6_DP_TYPE_C_PORT_CTRL_TYPE == _PORT_CONTROLLER_USER))
            return UserCommonPortControllerUpdateConfig(_D6_INPUT_PORT, enumMultiFunc, enumPinAssignmentCap);
#endif
            break;
#endif

        default:

            return _FAIL;

            break;
    }
    return _FAIL;
}

//--------------------------------------------------
// Description  : Return CC Attached Status to SysSource According to SysTypeC State
// Input Value  : ucInputPort --> Inputput
// Output Value : CC Attach Status (_TRUE / _FALSE)
//--------------------------------------------------
bit SysTypeCGetCcAttach(BYTE ucInputPort)
{
    switch(GET_TYPE_C_STATE(ucInputPort))
    {
        case _TYPE_C_ATTACHED_STATE:
        case _TYPE_C_ALT_MODE_READY_STATE:

            return _TRUE;

            break;

        case _TYPE_C_UNATTACH_STATE:
        default:

            return _FALSE;

            break;

        case _TYPE_C_RECONNECT_STATE:

            // CC Attach Status Not Change : Return Status From SysSource
            switch(ucInputPort)
            {
#if(_D0_DP_TYPE_C_SUPPORT == _ON)
                case _D0_INPUT_PORT:

                    return GET_D0_CABLE_STATUS();

                    break;
#endif

#if(_D1_DP_TYPE_C_SUPPORT == _ON)
                case _D1_INPUT_PORT:

                    return GET_D1_CABLE_STATUS();

                    break;
#endif

#if(_D6_DP_TYPE_C_SUPPORT == _ON)
                case _D6_INPUT_PORT:

                    return GET_D6_CABLE_STATUS();

                    break;
#endif

                default:

                    return _FALSE;

                    break;
            }

            break;
    }
    return _FALSE;
}

//--------------------------------------------------
// Description  : Return Alt Mode Ready Statsu to SysSource According to SysTypeC State
// Input Value  : ucInputPort --> Inputput
// Output Value : CC Attach Status (_TRUE / _FALSE)
//--------------------------------------------------
bit SysTypeCGetAltModeReady(BYTE ucInputPort)
{
    switch(GET_TYPE_C_STATE(ucInputPort))
    {
        case _TYPE_C_ALT_MODE_READY_STATE:

            return _TRUE;

            break;

        case _TYPE_C_UNATTACH_STATE:
        case _TYPE_C_ATTACHED_STATE:
        default:

            return _FALSE;

            break;

        case _TYPE_C_RECONNECT_STATE:

            // Alt Mode Status Not Change : Return Status From SysSource
            switch(ucInputPort)
            {
#if(_D0_DP_TYPE_C_SUPPORT == _ON)
                case _D0_INPUT_PORT:

                    return GET_D0_DP_TYPE_C_ALTMODE_STATUS();

                    break;
#endif

#if(_D1_DP_TYPE_C_SUPPORT == _ON)
                case _D1_INPUT_PORT:

                    return GET_D1_DP_TYPE_C_ALTMODE_STATUS();

                    break;
#endif

#if(_D6_DP_TYPE_C_SUPPORT == _ON)
                case _D6_INPUT_PORT:

                    return GET_D6_DP_TYPE_C_ALTMODE_STATUS();

                    break;
#endif

                default:

                    return _FALSE;

                    break;
            }

            break;
    }
    return _FALSE;
}

//--------------------------------------------------
// Description  : Trnaslate ucInputPort into Type-C Port Index For Macro Usage
// Input Value  : ucInputPort
// Output Value : Type-C Port Index
//--------------------------------------------------
BYTE SysTypeCGetTypeCIndex(BYTE ucInputPort)
{
    BYTE ucIndex = 0x00;

#if(_D0_DP_TYPE_C_SUPPORT == _ON)

    if(ucInputPort == _D0_INPUT_PORT)
    {
        return ucIndex;
    }
    else
    {
        ucIndex = ucIndex + 1;
    }

#endif

#if(_D1_DP_TYPE_C_SUPPORT == _ON)

    if(ucInputPort == _D1_INPUT_PORT)
    {
        return ucIndex;
    }
    else
    {
        ucIndex = ucIndex + 1;
    }

#endif

#if(_D6_DP_TYPE_C_SUPPORT == _ON)

    if(ucInputPort == _D6_INPUT_PORT)
    {
        return ucIndex;
    }

#endif

    // ucInputPort Invalid : Show Warning Message
    DebugMessageSystem("8. Invalid InputPort For TypeC Index", ucInputPort);

    return ucIndex;
}

//--------------------------------------------------
// Description  : Trnaslate Alt. Mode Pin Assignment to DP Lane Count
// Input Value  : ucPinAssignment
// Output Value : EnumDpLaneCount -> _DP_LINK_1_LANE / _DP_LINK_2_LANE / _DP_LINK_4_LANE
//--------------------------------------------------
EnumDpLaneCount SysTypeCGetAltModeLaneCnt(EnumTypeCPinCfgType enumPinAssignment)
{
    EnumDpLaneCount enumAltModeLaneCnt = _DP_LINK_4_LANE;
    switch(enumPinAssignment)
    {
        case _TYPE_C_PIN_ASSIGNMENT_C:
        case _TYPE_C_PIN_ASSIGNMENT_E:

            enumAltModeLaneCnt = _DP_LINK_4_LANE;

            break;

        case _TYPE_C_PIN_ASSIGNMENT_D:

            enumAltModeLaneCnt = _DP_LINK_2_LANE;

            break;


        default:

            DebugMessageSystem("8. Get Alt Mode Lane Count with Invalid Pin Assignment:", enumPinAssignment);

            break;
    }

    DebugMessageSystem("8. Set Alt Mode Lane Count to:", enumAltModeLaneCnt);

    return enumAltModeLaneCnt;
}

//--------------------------------------------------
// Description  : Update OSD Lane Count
// Input Value  : ucInputPort --> Inputput, enumDpLaneCount : _DP_LINK_1_LANE / _DP_LINK_2_LANE / _DP_LINK_4_LANE
// Output Value : NONE
//--------------------------------------------------
void SysTypeCSwitchOSDLaneCount(BYTE ucInputPort, EnumDpLaneCount enumDpLaneCount)
{
    switch(ucInputPort)
    {
#if(_D0_DP_TYPE_C_SUPPORT == _ON)
        case _D0_INPUT_PORT:

            UserCommonNVRamSetSystemData(_DP_D0_LANES, enumDpLaneCount);

            break;
#endif

#if(_D1_DP_TYPE_C_SUPPORT == _ON)
        case _D1_INPUT_PORT:

            UserCommonNVRamSetSystemData(_DP_D1_LANES, enumDpLaneCount);

            break;
#endif

#if(_D6_DP_TYPE_C_SUPPORT == _ON)
        case _D6_INPUT_PORT:

            UserCommonNVRamSetSystemData(_DP_D6_LANES, enumDpLaneCount);

            break;
#endif

        default:
            break;
    }

    UserCommonNVRamSaveSystemData();
}

//--------------------------------------------------
// Description  : Set Capability Change Flag For External Use
// Input Value  : ucInputPort --> Inputput
// Output Value : NONE
//--------------------------------------------------
void SysTypeCSetCapabilityChangeFlag(BYTE ucInputPort)
{
    switch(ucInputPort)
    {
#if(_D0_DP_TYPE_C_SUPPORT == _ON)
        case _D0_INPUT_PORT:

            SET_TYPE_C_CAPABILITY_CHG(_D0_INPUT_PORT);

            break;
#endif

#if(_D1_DP_TYPE_C_SUPPORT == _ON)
        case _D1_INPUT_PORT:

            SET_TYPE_C_CAPABILITY_CHG(_D1_INPUT_PORT);

            break;
#endif

#if(_D6_DP_TYPE_C_SUPPORT == _ON)
        case _D6_INPUT_PORT:

            SET_TYPE_C_CAPABILITY_CHG(_D6_INPUT_PORT);

            break;
#endif

        default:
            break;
    }
}

#if(((_D0_DP_TYPE_C_SUPPORT == _ON) && (_D0_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS)) || ((_D1_DP_TYPE_C_SUPPORT == _ON) && (_D1_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS)) || ((_D6_DP_TYPE_C_SUPPORT == _ON) && (_D6_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS)))
//--------------------------------------------------
// Description  : Set Type C State to Unattach State
// Input Value  : ucInputPort --> Inputput
// Output Value : NONE
//--------------------------------------------------
void SysTypeCSwitchToUnattachState(BYTE ucInputPort)
{
    switch(ucInputPort)
    {
#if((_D0_DP_TYPE_C_SUPPORT == _ON) && (_D0_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS))
        case _D0_INPUT_PORT:

            SET_TYPE_C_STATE(_D0_INPUT_PORT, _TYPE_C_UNATTACH_STATE);

            break;
#endif

#if((_D1_DP_TYPE_C_SUPPORT == _ON) && (_D1_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS))
        case _D1_INPUT_PORT:

            SET_TYPE_C_STATE(_D1_INPUT_PORT, _TYPE_C_UNATTACH_STATE);

            break;
#endif

#if((_D6_DP_TYPE_C_SUPPORT == _ON) && (_D6_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS))
        case _D6_INPUT_PORT:

            SET_TYPE_C_STATE(_D6_INPUT_PORT, _TYPE_C_UNATTACH_STATE);

            break;
#endif

        default:
            break;
    }
}
#endif  // End of #if(((_D0_DP_TYPE_C_SUPPORT == _ON) && (_D0_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS)) || ((_D1_DP_TYPE_C_SUPPORT == _ON) && (_D1_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS)) || ((_D6_DP_TYPE_C_SUPPORT == _ON) && (_D6_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS)))

//--------------------------------------------------
// Description  : Cancel Timer Event Which Set Type C to Unattach State
// Input Value  : ucInputPort --> Inputput
// Output Value : NONE
//--------------------------------------------------
void SysTypeCCancelUnattachTimerEvent(BYTE ucInputPort)
{
    switch(ucInputPort)
    {
#if((_D0_DP_TYPE_C_SUPPORT == _ON) && (_D0_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS))
        case _D0_INPUT_PORT:

            ScalerTimerCancelTimerEvent(_SYSTEM_TIMER_EVENT_D0_TYPE_C_UNATTACH);

            break;
#endif

#if((_D1_DP_TYPE_C_SUPPORT == _ON) && (_D1_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS))
        case _D1_INPUT_PORT:

            ScalerTimerCancelTimerEvent(_SYSTEM_TIMER_EVENT_D1_TYPE_C_UNATTACH);

            break;
#endif

#if((_D6_DP_TYPE_C_SUPPORT == _ON) && (_D6_DP_TYPE_C_DISCRETE_PORT_CTRL_LINK != _DISCRETE_PORT_CTRL_USE_SMBUS))
        case _D6_INPUT_PORT:

            ScalerTimerCancelTimerEvent(_SYSTEM_TIMER_EVENT_D6_TYPE_C_UNATTACH);

            break;
#endif

        default:

            break;
    }
}

#if(_DP_USB_HUB_SUPPORT == _ON)
//--------------------------------------------------
// Description  : Temperory Function to SysDp For Hub Process
// Input Value  : NONE
// Output Value : NONE
//--------------------------------------------------
BYTE SysTypeCGetDpLaneCount(BYTE ucInputPort)
{
    return SysTypeCGetAltModeLaneCnt(GET_TYPE_C_PIN_ASSIGNMENT(ucInputPort));
}

//--------------------------------------------------
// Description  : Type-C Usb Hub Proc
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void SysTypeCUsbHubProc(BYTE ucInputPort)
{
    if(UserInterfaceTypeCUSBSupport(ucInputPort) == _TRUE)
    {
        SysTypeCUsbHubDetectProc(ucInputPort);
        SysTypeCUsbHubConfigProc(ucInputPort, SysTypeCGetDpLaneCount(ucInputPort));
    }
}

//--------------------------------------------------
// Description  : Detect Usb Hub Info
// Input Value  : ucInputPort --> Input Port
// Output Value : None
//--------------------------------------------------
void SysTypeCUsbHubDetectProc(BYTE ucInputPort)
{
    switch(ucInputPort)
    {
#if(_D0_DP_USB_HUB_SUPPORT == _ON)
        case _D0_INPUT_PORT:

            SysTypeCD0UsbHubDetectProc();

            break;
#endif

#if(_D1_DP_USB_HUB_SUPPORT == _ON)
        case _D1_INPUT_PORT:

            SysTypeCD1UsbHubDetectProc();

            break;
#endif


#if(_D6_DP_USB_HUB_SUPPORT == _ON)
        case _D6_INPUT_PORT:

            SysTypeCD6UsbHubDetectProc();

            break;
#endif

        default:
            break;
    }
}

//--------------------------------------------------
// Description  : Adjust Type-C Dp Lanes
// Input Value  : ucInputPort --> Input Port
//                ucDpLanes   --> Target Dp Lanes
// Output Value : None
//--------------------------------------------------
void SysTypeCUsbHubConfigProc(BYTE ucInputPort, BYTE ucDpLanes)
{
    if(ucDpLanes == _DP_TWO_LANE)
    {
        switch(ucInputPort)
        {
#if(_D0_DP_USB_HUB_SUPPORT == _ON)
            case _D0_INPUT_PORT:

                if(GET_D0_USB_HUB_MODE_STATE() != _USB_MODE_STATUS_SS_STATE)
                {
                    if(GET_D0_TYPE_C_USB_HUB_INFO() == 0x00)
                    {
                        break;
                    }

                    if(UserCommonUsbHubSetSSMode(_D0_INPUT_PORT, _ENABLE) == _TRUE)
                    {
                        SET_D0_USB_HUB_MODE_STATE(_USB_MODE_STATUS_SS_STATE);
                        ScalerTimerReactiveTimerEvent(SysTypeCGetUsbHubSetU3ReadyDelayTime(_D0_INPUT_PORT), _SYSTEM_TIMER_EVENT_D0_USBHUB_DETECT);
                    }
                }

                break;
#endif

#if(_D1_DP_USB_HUB_SUPPORT == _ON)
            case _D1_INPUT_PORT:

                if(GET_D1_USB_HUB_MODE_STATE() != _USB_MODE_STATUS_SS_STATE)
                {
                    if(GET_D1_TYPE_C_USB_HUB_INFO() == 0x00)
                    {
                        break;
                    }

                    if(UserCommonUsbHubSetSSMode(_D1_INPUT_PORT, _ENABLE) == _TRUE)
                    {
                        SET_D1_USB_HUB_MODE_STATE(_USB_MODE_STATUS_SS_STATE);
                        ScalerTimerReactiveTimerEvent(SysTypeCGetUsbHubSetU3ReadyDelayTime(_D1_INPUT_PORT), _SYSTEM_TIMER_EVENT_D1_USBHUB_DETECT);
                    }
                }

                break;
#endif

#if(_D6_DP_USB_HUB_SUPPORT == _ON)
            case _D6_INPUT_PORT:

                if(GET_D6_USB_HUB_MODE_STATE() != _USB_MODE_STATUS_SS_STATE)
                {
                    if(GET_D6_TYPE_C_USB_HUB_INFO() == 0x00)
                    {
                        break;
                    }

                    if(UserCommonUsbHubSetSSMode(_D6_INPUT_PORT, _ENABLE) == _TRUE)
                    {
                        SET_D6_USB_HUB_MODE_STATE(_USB_MODE_STATUS_SS_STATE);
                        ScalerTimerReactiveTimerEvent(SysTypeCGetUsbHubSetU3ReadyDelayTime(_D6_INPUT_PORT), _SYSTEM_TIMER_EVENT_D6_USBHUB_DETECT);
                    }
                }

                break;
#endif

            default:
                break;
        }
    }
    else
    {
        switch(ucInputPort)
        {
#if(_D0_DP_USB_HUB_SUPPORT == _ON)
            case _D0_INPUT_PORT:

                if(GET_D0_USB_HUB_MODE_STATE() != _USB_MODE_STATUS_DETECT_SS_STATE)
                {
                    if(UserCommonUsbHubSetSSMode(_D0_INPUT_PORT, _DISABLE) == _TRUE)
                    {
                        SET_D0_USB_HUB_MODE_STATE(_USB_MODE_STATUS_DETECT_SS_STATE);
                        ScalerTimerReactiveTimerEvent(SysTypeCGetUsbHubSetU3ReadyDelayTime(_D0_INPUT_PORT), _SYSTEM_TIMER_EVENT_D0_USBHUB_DETECT);
                    }
                }

                break;
#endif

#if(_D1_DP_USB_HUB_SUPPORT == _ON)
            case _D1_INPUT_PORT:

                if(GET_D1_USB_HUB_MODE_STATE() != _USB_MODE_STATUS_DETECT_SS_STATE)
                {
                    if(UserCommonUsbHubSetSSMode(_D1_INPUT_PORT, _DISABLE) == _TRUE)
                    {
                        SET_D1_USB_HUB_MODE_STATE(_USB_MODE_STATUS_DETECT_SS_STATE);
                        ScalerTimerReactiveTimerEvent(SysTypeCGetUsbHubSetU3ReadyDelayTime(_D1_INPUT_PORT), _SYSTEM_TIMER_EVENT_D1_USBHUB_DETECT);
                    }
                }

                break;
#endif

#if(_D6_DP_USB_HUB_SUPPORT == _ON)
            case _D6_INPUT_PORT:

                if(GET_D6_USB_HUB_MODE_STATE() != _USB_MODE_STATUS_DETECT_SS_STATE)
                {
                    if(UserCommonUsbHubSetSSMode(_D6_INPUT_PORT, _DISABLE) == _TRUE)
                    {
                        SET_D6_USB_HUB_MODE_STATE(_USB_MODE_STATUS_DETECT_SS_STATE);
                        ScalerTimerReactiveTimerEvent(SysTypeCGetUsbHubSetU3ReadyDelayTime(_D6_INPUT_PORT), _SYSTEM_TIMER_EVENT_D6_USBHUB_DETECT);
                    }
                }

                break;
#endif
            default:
                break;
        }
    }
}

//--------------------------------------------------
// Description  : Set Usb Hub Config U3 Delay Time
// Input Value  : ucInputPort --> Input Port
// Output Value : Usb Hub Info
//--------------------------------------------------
WORD SysTypeCGetUsbHubSetU3ReadyDelayTime(BYTE ucInputPort)
{
    switch(ucInputPort)
    {
#if(_D0_DP_USB_HUB_SUPPORT == _ON)

        case _D0_INPUT_PORT:

            if(UserInterfaceTypeCUsbHubU3InfoDectectUserFlow(_D0_INPUT_PORT) == _TRUE)
            {
                return SEC(0);
            }
            else
            {
                return SEC(2);
            }
#endif

#if(_D1_DP_USB_HUB_SUPPORT == _ON)

        case _D1_INPUT_PORT:

            if(UserInterfaceTypeCUsbHubU3InfoDectectUserFlow(_D1_INPUT_PORT) == _TRUE)
            {
                return SEC(0);
            }
            else
            {
                return SEC(2);
            }
#endif

#if(_D6_DP_USB_HUB_SUPPORT == _ON)
        case _D6_INPUT_PORT:

            if(UserInterfaceTypeCUsbHubU3InfoDectectUserFlow(_D6_INPUT_PORT) == _TRUE)
            {
                return SEC(0);
            }
            else
            {
                return SEC(2);
            }
#endif

        default:
            break;
    }

    return SEC(0);
}

#if(_D0_DP_USB_HUB_SUPPORT == _ON)
//--------------------------------------------------
// Description  : Detect SS Device
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void SysTypeCD0UsbHubDetectProc(void)
{
    BYTE ucUsbHubInfo = 0x00;

    CLR_D0_USB_HUB_PLUG_DEVICE_CHANGE_FLG();

    switch(GET_D0_USB_HUB_MODE_STATE())
    {
        case _USB_MODE_STATUS_INITIAL:

            SET_D0_USB_HUB_MODE_STATE(_USB_MODE_STATUS_DETECT_SS_STATE);
            SET_D0_USB_HUB_SS_DEVICE_DETECT_FLG();

            break;

        case _USB_MODE_STATUS_DETECT_SS_STATE:
        case _USB_MODE_STATUS_SS_STATE:

            if((GET_D0_USB_HUB_SS_DEVICE_DETECT_FLG() == _TRUE) && (UserInterfaceTypeCGetUSBSupportStatus(_D0_INPUT_PORT) == _ON))
            {
                CLR_D0_USB_HUB_SS_DEVICE_DETECT_FLG();
                ScalerTimerActiveTimerEvent(UserCommonUsbHubSetPollingStep(_D0_INPUT_PORT), _SYSTEM_TIMER_EVENT_D0_USBHUB_DETECT);

                ucUsbHubInfo = UserCommonUsbHubDetectSSDevicePlugInfo(_D0_INPUT_PORT);

                if(GET_D0_TYPE_C_USB_HUB_INFO() != ucUsbHubInfo)
                {
                    SET_D0_USB_HUB_PLUG_DEVICE_CHANGE_FLG();
                    SET_D0_TYPE_C_USB_HUB_INFO(ucUsbHubInfo);
                }
            }

            break;

        default:
        case _USB_MODE_STATUS_PS_STATE:
        case _USB_MODE_STATUS_PD_STATE:

            break;
    }
}
#endif // End of #if(_D0_DP_USB_HUB_SUPPORT == _ON)

#if(_D1_DP_USB_HUB_SUPPORT == _ON)
//--------------------------------------------------
// Description  : Detect SS Device
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void SysTypeCD1UsbHubDetectProc(void)
{
    BYTE ucUsbHubInfo = 0x00;

    CLR_D1_USB_HUB_PLUG_DEVICE_CHANGE_FLG();

    switch(GET_D1_USB_HUB_MODE_STATE())
    {
        case _USB_MODE_STATUS_INITIAL:

            SET_D1_USB_HUB_MODE_STATE(_USB_MODE_STATUS_DETECT_SS_STATE);
            SET_D1_USB_HUB_SS_DEVICE_DETECT_FLG();

            break;

        case _USB_MODE_STATUS_DETECT_SS_STATE:
        case _USB_MODE_STATUS_SS_STATE:

            if((GET_D1_USB_HUB_SS_DEVICE_DETECT_FLG() == _TRUE) && (UserInterfaceTypeCGetUSBSupportStatus(_D1_INPUT_PORT) == _ON))
            {
                CLR_D1_USB_HUB_SS_DEVICE_DETECT_FLG();
                ScalerTimerActiveTimerEvent(UserCommonUsbHubSetPollingStep(_D1_INPUT_PORT), _SYSTEM_TIMER_EVENT_D1_USBHUB_DETECT);

                ucUsbHubInfo = UserCommonUsbHubDetectSSDevicePlugInfo(_D1_INPUT_PORT);

                if(GET_D1_TYPE_C_USB_HUB_INFO() != ucUsbHubInfo)
                {
                    SET_D1_USB_HUB_PLUG_DEVICE_CHANGE_FLG();
                    SET_D1_TYPE_C_USB_HUB_INFO(ucUsbHubInfo);
                }
            }

            break;

        default:
        case _USB_MODE_STATUS_PS_STATE:
        case _USB_MODE_STATUS_PD_STATE:

            break;
    }
}
#endif // End of #if(_D1_DP_USB_HUB_SUPPORT == _ON)

#if(_D6_DP_USB_HUB_SUPPORT == _ON)
//--------------------------------------------------
// Description  : Detect SS Device
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void SysTypeCD6UsbHubDetectProc(void)
{
    BYTE ucUsbHubInfo = 0x00;

    CLR_D6_USB_HUB_PLUG_DEVICE_CHANGE_FLG();

    switch(GET_D6_USB_HUB_MODE_STATE())
    {
        case _USB_MODE_STATUS_INITIAL:

            SET_D6_USB_HUB_MODE_STATE(_USB_MODE_STATUS_DETECT_SS_STATE);
            SET_D6_USB_HUB_SS_DEVICE_DETECT_FLG();

            break;

        case _USB_MODE_STATUS_DETECT_SS_STATE:
        case _USB_MODE_STATUS_SS_STATE:

            if((GET_D6_USB_HUB_SS_DEVICE_DETECT_FLG() == _TRUE) && (UserInterfaceTypeCGetUSBSupportStatus(_D6_INPUT_PORT) == _ON))
            {
                CLR_D6_USB_HUB_SS_DEVICE_DETECT_FLG();
                ScalerTimerActiveTimerEvent(UserCommonUsbHubSetPollingStep(_D6_INPUT_PORT), _SYSTEM_TIMER_EVENT_D6_USBHUB_DETECT);

                ucUsbHubInfo = UserCommonUsbHubDetectSSDevicePlugInfo(_D6_INPUT_PORT);

                if(GET_D6_TYPE_C_USB_HUB_INFO() != ucUsbHubInfo)
                {
                    SET_D6_USB_HUB_PLUG_DEVICE_CHANGE_FLG();
                    SET_D6_TYPE_C_USB_HUB_INFO(ucUsbHubInfo);
                }
            }

            break;

        default:
        case _USB_MODE_STATUS_PS_STATE:
        case _USB_MODE_STATUS_PD_STATE:

            break;
    }
}
#endif // End of #if(_D6_DP_USB_HUB_SUPPORT == _ON)

//--------------------------------------------------
// Description  : For OSD Handler to do Process According to USB Hub Info
// Input Value  : None
// Output Value : None
//--------------------------------------------------
void SysTypeCOsdHubProc(void)
{
    BYTE ucUsbHubInfo = 0x00;

#if(_D0_DP_USB_HUB_SUPPORT == _ON)
    if(SysTypeCGetUsbHubChangeFlg(_D0_INPUT_PORT) == _TRUE)
    {
        ucUsbHubInfo = SysTypeCGetUsbHubDeviceInfo(_D0_INPUT_PORT);
        UserInterfaceTypeCOsdHubProc(_D0_INPUT_PORT, ucUsbHubInfo);
    }
#endif

#if(_D1_DP_USB_HUB_SUPPORT == _ON)
    if(SysTypeCGetUsbHubChangeFlg(_D1_INPUT_PORT) == _TRUE)
    {
        ucUsbHubInfo = SysTypeCGetUsbHubDeviceInfo(_D1_INPUT_PORT);
        UserInterfaceTypeCOsdHubProc(_D1_INPUT_PORT, ucUsbHubInfo);
    }
#endif

#if(_D6_DP_USB_HUB_SUPPORT == _ON)
    if(SysTypeCGetUsbHubChangeFlg(_D6_INPUT_PORT) == _TRUE)
    {
        ucUsbHubInfo = SysTypeCGetUsbHubDeviceInfo(_D6_INPUT_PORT);
        UserInterfaceTypeCOsdHubProc(_D6_INPUT_PORT, ucUsbHubInfo);
    }
#endif
}

//--------------------------------------------------
// Description  : Get Usb Hub Device Info Change Flag
// Input Value  : ucInputPort --> Input Port
// Output Value : _TRUE / _FALSE
//--------------------------------------------------
bit SysTypeCGetUsbHubChangeFlg(BYTE ucInputPort)
{
    switch(ucInputPort)
    {
#if(_D0_DP_USB_HUB_SUPPORT == _ON)

        case _D0_INPUT_PORT:

            return GET_D0_USB_HUB_PLUG_DEVICE_CHANGE_FLG();
#endif

#if(_D1_DP_USB_HUB_SUPPORT == _ON)

        case _D1_INPUT_PORT:

            return GET_D1_USB_HUB_PLUG_DEVICE_CHANGE_FLG();
#endif

#if(_D6_DP_USB_HUB_SUPPORT == _ON)

        case _D6_INPUT_PORT:

            return GET_D6_USB_HUB_PLUG_DEVICE_CHANGE_FLG();
#endif

        default:
            break;
    }

    return 0;
}

//--------------------------------------------------
// Description  : Get Usb Hub Device Info
// Input Value  : ucInputPort --> Input Port
// Output Value : Usb Hub Info
//--------------------------------------------------
BYTE SysTypeCGetUsbHubDeviceInfo(BYTE ucInputPort)
{
    switch(ucInputPort)
    {
#if(_D0_DP_USB_HUB_SUPPORT == _ON)

        case _D0_INPUT_PORT:

            return GET_D0_TYPE_C_USB_HUB_INFO();
#endif

#if(_D1_DP_USB_HUB_SUPPORT == _ON)

        case _D1_INPUT_PORT:

            return GET_D1_TYPE_C_USB_HUB_INFO();
#endif

#if(_D6_DP_USB_HUB_SUPPORT == _ON)

        case _D6_INPUT_PORT:

            return GET_D6_TYPE_C_USB_HUB_INFO();
#endif

        default:
            break;
    }

    return 0;
}

#endif // End of #if(_DP_USB_HUB_SUPPORT == _ON)
#endif // End of #if(_DP_TYPE_C_SUPPORT == _ON)

